#ifndef _INTERFACE_CONSOLE_EQUATION_MENU_
#define _INTERFACE_CONSOLE_EQUATION_MENU_

#include "..\..\mathematics\algebra\equation.h"
using namespace science::mathematics::algebra;

#include <memory>
#include <iostream>
#include <string>
using std::cout;
using std::cin;
using std::endl;

#include "console_settings.h"

namespace science
{
	namespace interface
	{
		namespace console
		{
			enum class EQUATION_MENU_OPTIONS
			{
				OPTION_EQUATION_CHECK_SOLUTION,
				OPTION_EQUATION_SAVING,
				OPTION_EQUATION_CLEAR_MEMORY,
				OPTION_EQUATION_EXIT,
				OPTION_EQUATION_UNKNOWN
			};

			class equation_menu
			{
			private:

				static std::shared_ptr<equation> _saved_equation;

			public:
				static EQUATION_MENU_OPTIONS show_menu()
				{
					console_settings::clear_screen();

					cout << "Choose option from the next menu:" << endl;
					cout << "  1 - check equation solution?." << endl;
					cout << "  2 - save equation in memory." << endl;
					cout << "  3 - clear memory." << endl;
					cout << "  4 - Exit program." << endl << endl;

					int option = console_settings::get_int_option("Your option? ");

					switch (option)
					{
					case 1:
						return EQUATION_MENU_OPTIONS::OPTION_EQUATION_CHECK_SOLUTION;
					case 2:
						return EQUATION_MENU_OPTIONS::OPTION_EQUATION_SAVING;
					case 3:
						return EQUATION_MENU_OPTIONS::OPTION_EQUATION_CLEAR_MEMORY;
					case 4:
						return EQUATION_MENU_OPTIONS::OPTION_EQUATION_EXIT;
					default:
						return EQUATION_MENU_OPTIONS::OPTION_EQUATION_UNKNOWN;
					}
				}

				static void run()
				{
					while (true)
					{
						EQUATION_MENU_OPTIONS option = equation_menu::show_menu();
						switch (option)
						{
						case science::interface::console::EQUATION_MENU_OPTIONS::OPTION_EQUATION_CHECK_SOLUTION:
							check_equation_solution();
							break;						
						case science::interface::console::EQUATION_MENU_OPTIONS::OPTION_EQUATION_SAVING:
							save_equation_in_memory();
							break;
						case science::interface::console::EQUATION_MENU_OPTIONS::OPTION_EQUATION_CLEAR_MEMORY:
							_saved_equation = nullptr;
							break;
						case science::interface::console::EQUATION_MENU_OPTIONS::OPTION_EQUATION_EXIT:
							return;
						case science::interface::console::EQUATION_MENU_OPTIONS::OPTION_EQUATION_UNKNOWN:
							cout << endl << "Invalid option, please choose again.." << endl;
							break;
						default:
							break;
						}
					};
				}

			public:

				static bool load_from_memory()
				{
					if (_saved_equation == nullptr)
						return false;

					char option = console_settings::get_char_option("Do you want so load the saved equation? ");
					if (option == 'Y' || option == 'y')
					{
						cout << "The loaded equation is : " << *(_saved_equation.get()) << endl;
						return true;
					}
					else
						return false;
				}

				static void load_two_equations(equation& eq1, equation& eq2)
				{
					if (load_from_memory())
						eq1 = *(_saved_equation.get());
					else
						eq1 = console_settings::get_from_user<equation>("Enter first equation : ");

					eq2 = console_settings::get_from_user<equation>("Enter second equation : ");
				}

				static equation load_one_equation()
				{
					if (load_from_memory())
						return *(_saved_equation.get());
					else
						return console_settings::get_from_user<equation>("Enter equation : ");
				}

				static void check_equation_solution()
				{
					console_settings::clear_screen();
					equation eq = load_one_equation();

					cout << "Enter the values of vars : ";
					std::map<char, double> lhs_vals;
					for (unsigned int i = 0; i < eq.get_lhs().get_max_power_term().get_variables_count(); i++)
					{
						double val; char var_name;
						cin >> var_name >> val;
						lhs_vals[var_name] = val;
					}

					if (eq.check_solution(lhs_vals))
						cout << "This is a solution of the equation." << endl;
					else
						cout << "This is not a solution of the equation." << endl;

					if (console_settings::do_again())
						check_equation_solution();
				}

				static void save_result_in_memory(equation frc)
				{
					if (console_settings::do_again("Save the result to memory? "))
					{
						_saved_equation = std::shared_ptr<equation>(new equation());
						*_saved_equation = frc;
					}
				}

				static void save_equation_in_memory()
				{
					console_settings::clear_screen();
					equation eq = console_settings::get_from_user<equation>("Enter equation : ");
					_saved_equation = std::shared_ptr<equation>(new equation());
					*_saved_equation = eq;
					cout << "Equation saved." << endl;
				}
			};

			std::shared_ptr<equation> equation_menu::_saved_equation = nullptr;
		}
	}
}

#endif